<?php
class Zen_View_Helper_Jstree_Widget extends Zend_View_Helper_Abstract {
	
	private $model;
	private $treeId;
	private $types=false;
	private $js = "";
	private $root_label = "";
	private $base_url = "";
	
	public function jstree_Widget($base_url, $model, $params = array()) {
		$this->_setBaseUrl($base_url);
        $this->_setModel($model);
        $this->_bootstrapJQuery();
        $this->_bootstarpTreeId();
        $this->_bootstrapPlugin($params);
		return $this->_bootcstrapHtml();		
	}
	
	private function _bootstrapJQuery () {
		$jquery = $this->view->jQuery();
        $jquery->enable(); // enable jQuery Core Library
        $jquery->addJavascriptFile('/cms/library/Zen/View/Helper/Jstree/jquery.cookie.js');
        $jquery->addJavascriptFile('/cms/library/Zen/View/Helper/Jstree/jquery.hotkeys.js');
        $jquery->addJavascriptFile('/cms/library/Zen/View/Helper/Jstree/jquery.jstree.js');
        $jquery->addJavascriptFile('/cms/library/Zen/View/Helper/Jstree/jstreegrid.js');
        $jquery->addStylesheet('/cms/library/Zen/View/Helper/Jstree/themes/default/style.css');
        $jquery->addStylesheet('/cms/library/Zen/View/Helper/Jstree/themes/custom.css');
        return $jquery;
	}

	private function _bootstarpTreeId() {
		$tree_id='jstree_' . $this->_getModel()->getTableName();
		$this->treeId = $tree_id;
		return $tree_id;
	}
	
	private function _bootstrapPlugin($params) {
		$events = $this->_bootstrapEvents();
		$tree_id = $this->_getTreeId();
		$params = $this->_bootstrapParams($params);
		$js = sprintf('%s("#%s").jstree(%s)'.$events,
                ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(),
                $tree_id,
                $params
        );
        $this->_appendJs($js);
		return $this;
	}
	
	private function _bootcstrapHtml() {
		$html="";
       	$html.=$this->renderControls();
		$html.=$this->_getTreeContainer();
		return $html;
	}
	
	private function _setBaseUrl($base_url) {
		$this->base_url = $base_url;
		return $this;
	}
	
	private function _getBaseUrl(){
		return $this->base_url;
	}
	
	private function _getTreeId(){
		return $this->treeId;
	}
	/**
	 * @return the $types
	 */
	public function getTypes() {
		return $this->types;
	}

	/**
	 * @param field_type $types
	 */
	public function setTypes($types) {
		$this->types = $types;
	}

	/**
	 * @return the $model
	 */
	private function _getModel() {
		return $this->model;
	}

	/**
	 * @param field_type $model
	 */
	private function _setModel($model) {
		$this->model = $model;
		$types=$this->model->getTypes();
		if($types){
			$this->setTypes($types);
		}
	}	
	
	private function _getTreeContainer () {
		$tree_id = $this->_getTreeId();
		return '<div id="'.$tree_id.'" name="'.$tree_id.'"></div>';
	}
	
	private function _bootstrapDefaultParams () {
		$url = '"'. $this->_getBaseUrl() .'"';
		$types = $this->_bootstrapTypes();
		$root_nodes = $this->_getRootNodes();
		$defaultParams = array(
   		    'plugins'=>array('themes', 'json_data', 'ui', 'crrm', 'cookies','dnd', 'search', 'types','hotkeys'),
      	    'hotkeys'=>array(
      	    'return'=>new Zend_Json_Expr(' function (n) {if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click();}$("#admin-update").trigger("click");return false}'),
      		'ctrl+s'=>new Zend_Json_Expr(' function (n) {$(".iframedialog").each(function(){
      			if($(this).dialog( "isOpen" )){
      						var btn=$(this).closest(".ui-dialog").find("button:last");
      						btn.trigger("click");
						}
					});	return false;}')
      		),
   		    
   		    'json_data'=>array(
      	    	'data' => $root_nodes,
      		    'progressive_render'=>true, 
     			'ajax'=>array(
        					'url'=>new Zend_Json_Expr($url),
      						'data'=>new Zend_Json_Expr(' function (n) {
								return {
								"operation" : "get_children", 
								"id" : n.attr ? n.attr("id").replace("item_","") : 0 
								};}' 
      						),
        					'type'=>'POST'
        				)
      		),
      		'types'=>array(
      		'valid_children' =>array('root'),
			'types' => $types,
      		),
      		'ui'=>array(
      			'initially_select' =>array('item_0')
      		),
      		'core'=>array(
      			'initially_open' =>array('item_0'),
      			"html_titles" => true
      		)
      		
		);
		$grid=$this->_getModel()->getGrid();
		if($grid!=false){
      		$defaultParams['grid']['columns']=$grid['columns'];
      		$defaultParams['plugins'][]='grid';
		}
		return $defaultParams;
	}
	
	private function _bootstrapTypes() {
		$types = $this->getTypes();
		$types_js=array();
		if(! $types) 
			return array();
		foreach ($types as $type=>$typeParams){
			if($type=='root'){
				$this->root_label = $typeParams['label'];
			}
			$jstype=array();
			if(isset($typeParams['icon'])){
				$jstype['icon']['image']=$typeParams['icon'];
			}
			if(isset($typeParams['valid_children'])){
				$jstype['valid_children']=$typeParams['valid_children'];
				if(($typeParams['valid_children']!="all") && ($typeParams['valid_children']!="none") ){
					$btns='$(".create-type").addClass( "disabled" );';
					foreach ($typeParams['valid_children'] as $valid){
						$btns.='$("#admin-create-'.$valid.'").removeClass( "disabled" );';
					}
				}
				if($typeParams['valid_children']=="all" ){
					$btns='$(".create-type").removeClass( "disabled" );';
				}
				if($typeParams['valid_children']=="none" ){
					$btns='$(".create-type").addClass( "disabled" );';
				}
				if(isset($typeParams['delete_node'])){
					if($typeParams['delete_node']==false){
						$btns.='$("#admin-delete").addClass( "disabled" );';
					}else{
						$btns.='$("#admin-delete").removeClass( "disabled" );';
					}
				}
				if($type=='root'){
						$btns.='$("#admin-update").addClass( "disabled" );';
				}else{
						$btns.='$("#admin-update").removeClass( "disabled" );';
				}
				$btns.='return (true);';
				$jstype['select_node']=new Zend_Json_Expr('function(){'.$btns.'}');
			}
			if(isset($typeParams['start_drag'])){
				$jstype['start_drag']=$typeParams['start_drag'];
			}
			if(isset($typeParams['move_node'])){
				$jstype['move_node']=$typeParams['move_node'];
			}
			if(isset($typeParams['delete_node'])){
				$jstype['delete_node']=$typeParams['delete_node'];
			}
			if(isset($typeParams['remove'])){
				$jstype['remove']=$typeParams['remove'];
			}
			$types_js[$type]=$jstype;		
		}
		return $types_js;
	}
	
	private function _bootstrapEvents() {
		$url = '"'. $this->_getBaseUrl() .'"';
		$tree_id = $this->treeId;
		$reorderJs='.bind("move_node.jstree", function (e, data) {
      						$("#'.$tree_id.'").jstree("lock");
							data.rslt.o.each(function (i) {
							var item_id=$(this).attr("id");
							$.post(
								'.$url.', 
								{	 
									"operation" : "reorder", 
									"id" : $(this).attr("id").replace("item_",""), 
									"parent_id" : data.rslt.np.attr("id").replace("item_",""), 
									"pos" : data.rslt.cp + i,
									"title" : data.rslt.name,
									"position" : data.rslt.p,
									"objectiveNodeId":	data.rslt.r.attr("id").replace("item_",""), 
									"copy" : data.rslt.cy ? 1 : 0
								}, 
								function (r) {
									$("#'.$tree_id.'").jstree("unlock");
									if(!r.status) {
										$.jstree.rollback(data.rlbk);
										$("#"+item_id+" a").trigger("click");
									}else {
										$(data.rslt.oc).attr("id", "item_" + r.id);
										if(data.rslt.cy && $(data.rslt.oc).children("UL").length) {
											data.inst.refresh(data.inst._get_parent(data.rslt.oc));
										}
									}
									
								}
							);
						})
							
					})';
      
		$deleteJs='.bind("delete_node.jstree", function (e, data) {
			$.post(
				'.$url.', 
				{ 
					"operation" : "delete_node", 
					"id" : data.rslt.obj.attr("id").replace("item_",""),
				}, 
				function (r) {
					if(!r.status) {
						$.jstree.rollback(data.rlbk);
					}
				}
			);
		})';
		$beforeJs='.bind("before.jstree", function (e, data) {
			if(data.func === "delete_node") {
				if(!confirm("Удалить элемент и всех его потомков?"))
				{return false;}
			}
		})';
		$loadJs='.bind("loaded.jstree", function (e, data) {
			$("li[rel=root] a:first").click();
		})';
		
		$loadNode='.bind("load_node.jstree",function(e, data){
			     var $nodes = data.inst._get_children(data.rslt.obj)
			     $.each($nodes, function(){
	      			if  ($(this).attr("active") == "0") {
	      				$(this).addClass("disabled");
	      			}
				});
		     });
		';
		return $beforeJs.$reorderJs.$deleteJs.$loadJs.$loadNode.";";
	}
	
	private function _bootstrapParams($params){
		$defaultParams = $this->_bootstrapDefaultParams();
        $params=array_merge($defaultParams,$params);
        $params=Zend_Json::encode(
          	  $params,
        	  false,
          	  array('enableJsonExprFinder' => true)
      	);
        $params=preg_replace('/\\\\\//', '/', $params);
		return $params;
	}
	
	private function _appendJs($js) {
		$jquery = $this->view->jQuery();
		$jquery->addOnLoad($js);
		return $this;
	}
	
	protected function renderControls(){
		$base_url = $this->_getBaseUrl();
		$controls=array();
		$control_panel='<div class="control_panel floatfixed clearfix">';
		$js="";
		$types = $this->getTypes();
		if($types){
			$helper=new Zend_View_Helper_Url();
			foreach ($types as $type=>$typeParams){
				if($type!="root"&&$type!="default"){
					if(isset($typeParams['form'])){
						$createUrl=$base_url;
						$controls[]=array(
	            						'uri'			=>  $base_url . "/type/$type/operation/create",
										'ico'			=>	'icon-plus icon-white',
										'class'			=>	'create-type btn btn-primary',
	                					'label'         => 	'Добавить '.$typeParams['label'],
	                					'title'			=> 	'Добавление нового элемента',  
	                					'id'			=> 	'create-'.$type,
	               					);
						$js.='$("#admin-create-'.$type.'").addClass("disabled").click(function(){
								if( $(this).hasClass("disabled") ) return false;
								var node=$("#'.$this->treeId.'").jstree("get_selected");		
								if(! node.attr("id")) return false;
								var parent_id=node.attr("id");
								createurl=$(this).attr("href");
				        		if(! createurl) return false;
					        		createurl=createurl+"/parent_id/"+parent_id;
					        		$(this).attr("href",createurl);
							});
						';
					}
				}				
			}
				
			$controls[]=array('uri'			=>  $base_url . "/operation/update",
							  'ico'			=>	'icon-pencil icon-white',
                			  'label'       => 'Редактировать',
                			  'title'		=> 'Редактирование элемента',  
                			  'id'			=> 'update',
							  'class' 		=> 'btn btn-success',
               				);
			$js.='$("#admin-update").addClass("disabled").click(function(){
						if( $(this).hasClass("disabled")) return false;
						var node=$("#'.$this->treeId.'").jstree("get_selected");
						if(node.attr("id")){
							var type =node.attr("rel");
							var id =node.attr("id");
							var editurl=$("#admin-update").attr("href");
							if(! editurl) return false;
							editurl=editurl+"/id/"+id+"/type/"+type;
							$("#admin-update").attr("href",editurl);
						}else{
							alert("Выберите элемент для редактирования");
							return false;
						}
					});';               					
            $controls[]=array('uri'			=>  $base_url,
                			  'label'       => 'Удалить',
                			  'title'		=> 'Удалить элемент',  
                			  'id'			=> 'delete',
                			  'class' 		=> 'btn btn-danger',	
                			  'ico'			=>'icon-trash icon-white',
               				);					
			$js.='$("#admin-delete").addClass("disabled").click(function(){
				if( $(this).hasClass("disabled")) return false;
				var node=$("#'.$this->treeId.'").jstree("get_selected");		
				if(node.attr("id")){
					$("#'.$this->treeId.'").jstree("delete_node",node);
				}else{
					alert("Выберите элемент для удаления");
				}
				return false;
			});';
		}
		if($controls){
			$this->_appendJs($js);
      	 	$container=new Zend_Navigation($controls);
      	 	$helper=new Zen_View_Helper_Menu_Admin();
      	 	$view=new Zend_View();
      	 	$helper->setView($view);
      	 	$control_panel.=$helper->renderMenu($container,array('ulClass'=>'btn-group ui-corner-all'))."</div><div style='height:55px'></div>";
		}	
		return $control_panel;	
	}
	
	private function _getRootNodes () {
		$model = $this->_getModel();
		$cfg = Zend_Registry::get ( 'cnf' );
		if (! $cfg->languages->multiLang || ! $model->getMultilang()) {
			return array('data'=>$this->root_label,'attr'=>array('id'=>'item_0','rel'=>'root'),'state'=>'closed');
		} else {
			$locale_model = new Locale_Model_List();
			$locale_list = $locale_model->getList(); 
			if (! $locale_list) {
				return array('data'=>$this->root_label,'attr'=>array('id'=>'item_0','rel'=>'root'),'state'=>'closed');
			} else {
				$nodes = array();
				foreach ( $locale_list as $item ) {
					$nodes[] = array('data'=>$this->root_label . "&nbsp;<b>({$item['alias']})</b>",'attr'=>array('id'=>$item['alias'],'rel'=>'root'),'state'=>'closed');
				}
				return $nodes;
			}
		}
	}
	
}